#include "header.h"
#include "unistd.h"

#define DEFAULT_MATRIX_SIZE 20
#define STACK_INIT_SIZE 50
#define STACK_BOTTOM_OPERATOR '\n'

#define COMPARE_LESS_THAN '<'
#define COMPARE_GREATE_THAN '>'
#define COMPARE_EQUAL '='

#define OPERATOR_NEWLINE '\n'
#define OPERATOR_ADD '+'
#define OPERATOR_SUB '-'
#define OPERATOR_LEFT_BRACKET '('
#define OPERATOR_RIGHT_BRACKET ')'
#define OPERATOR_MUL '*'
#define OPERATOR_DIV '/'

typedef char StackType;

struct Stack{
    StackType * base;
    StackType * top;
    int stacksize;
};

void initStack(Stack &s){
    s.base = (StackType*)malloc(STACK_INIT_SIZE*sizeof(StackType));
    if(!s.base){
        cout<<"error: malloc fail"<<endl;
        exit(0);
    }
    s.top = s.base;
    s.stacksize = STACK_INIT_SIZE;
}
bool isStackEmpty(Stack & s){
    if(s.base == s.top)
        return true;
    else
        return false;
}

void pushStack(Stack &s,const StackType &e){
    if((s.top - s.base) == s.stacksize){
        s.base = (StackType*)realloc(s.base,(s.stacksize + 1)*sizeof(StackType));
        s.top = s.base + s.stacksize;
        s.stacksize++;
    }
    *(s.top) = e;
    s.top++;
}
StackType popStack(Stack &s){
    static StackType e;
    if(s.top != s.base){
        s.top--;
        e = *(s.top);
    }
    return e;
}

void printStack(Stack &s){
    Stack temp = s;
    while(temp.base < temp.top){
        temp.top--;
    }
    cout<<endl;
}

StackType getTop(Stack &S){
    static StackType e;
    if(S.top>S.base){
        e=*(S.top-1);
        return e;
    }
}
bool isEnd(StackType & e){
    switch (e) {
    case STACK_BOTTOM_OPERATOR:
        return true;
        break;
    default:
        break;
    }
    return false;
}

StackType judgePrecede(const StackType & value1\
                      ,const StackType & value2){
    static StackType rtn;
    switch (value2) {
    case OPERATOR_ADD:

    case OPERATOR_SUB:
        if(value1 == OPERATOR_LEFT_BRACKET \
                || value1 == OPERATOR_NEWLINE)
            rtn = COMPARE_LESS_THAN;
        else
            rtn = COMPARE_GREATE_THAN;
        break;

    case OPERATOR_MUL:

    case OPERATOR_DIV:
        if(value1 == OPERATOR_MUL \
                || value1 == OPERATOR_DIV\
                || value1 == OPERATOR_RIGHT_BRACKET)
            rtn = COMPARE_GREATE_THAN;
        else
            rtn = COMPARE_LESS_THAN;
        break;

    case OPERATOR_LEFT_BRACKET:
        if(value1 == OPERATOR_RIGHT_BRACKET){
            cout<<"括号不匹配"<<endl;
            exit(0);
        }else{
            rtn = COMPARE_LESS_THAN;
        }
        break;
    case OPERATOR_RIGHT_BRACKET:
        switch(value1){
        case OPERATOR_LEFT_BRACKET:
            rtn = COMPARE_EQUAL;
            break;
        case OPERATOR_NEWLINE:
            cout<<"缺乏左括号"<<endl;
            exit(0);
        default:
            rtn = COMPARE_GREATE_THAN;
        }
    case OPERATOR_NEWLINE:
        switch(value1){
        case OPERATOR_NEWLINE:
            rtn = COMPARE_EQUAL;
            break;
        case OPERATOR_LEFT_BRACKET:
            cout<<"缺乏右括号"<<endl;
            exit(0);
        default:
            rtn = COMPARE_GREATE_THAN;
        }
    }
    return rtn;
}

StackType operate(StackType & num1,StackType & op,StackType & num2){
    switch(op){
    case OPERATOR_ADD: return (num1 + num2);
    case OPERATOR_SUB: return (num1 - num2);
    case OPERATOR_MUL: return (num1 * num2);
    case OPERATOR_DIV: return (num1 / num2);
    }
}

void destorySatck(Stack & s){
    free(s.base);
    s.top = s.base;
    s.stacksize = 0;
}

int main(void){
    Stack OPTR, OPND;
    StackType opnd_a, opnd_b, input, top_elememnt,input_cache;
    input = getchar();
    initStack(OPTR);
    initStack(OPND);
    pushStack(OPTR,STACK_BOTTOM_OPERATOR);
    top_elememnt = getTop(OPTR);
    while(input != STACK_BOTTOM_OPERATOR \
          || top_elememnt != STACK_BOTTOM_OPERATOR){

        if(isEnd(input)){

            switch(judgePrecede(input,top_elememnt)){
            case COMPARE_LESS_THAN:
                pushStack(OPTR,input);
                input = getchar();
                break;
            case COMPARE_EQUAL:
                top_elememnt = popStack(OPTR);
                input = getchar();
                break;
            case COMPARE_GREATE_THAN:
                top_elememnt = popStack(OPTR);
                opnd_a = popStack(OPND);
                opnd_b = popStack(OPND);
                pushStack(OPND,operate(opnd_a,top_elememnt,opnd_b));
            }
        }else if(input >= '0' && input <= '9'){
            input_cache = 0;
            while(input >= '0' && input <= '9'){
                input_cache = input_cache * 10 + input - '0';
                input = getchar();
            }
            pushStack(OPND,input_cache);
        }else{
            cout<<"出现非法字符"<<endl;
            destorySatck(OPND);
            destorySatck(OPTR);
            exit(0);
        }
        top_elememnt = getTop(OPND);
        if(isStackEmpty(OPND)){
            cout<<"表达式不正确"<<endl;
            destorySatck(OPND);
            destorySatck(OPTR);
            exit(0);
        }
    }
    destorySatck(OPND);
    destorySatck(OPTR);
    cout<<"结果是:"<<top_elememnt<<endl;
    return 0;
}
